package org.gvp.generator.core.writer.impl;

import org.gvp.generator.constant.ImportConstant;
import org.gvp.generator.core.writer.AbstractFileWriter;
import org.gvp.generator.props.CreateProps;
import org.gvp.generator.props.ProjectProps;
import org.gvp.generator.table.TableInfo;

import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 数据层实现类代码生成类
 */
public class ServiceImplFileWriter extends AbstractFileWriter {
    @Override
    public void execute(TableInfo tableInfo, ProjectProps project) {
        String upName = tableInfo.getUpperName();
        String classDefine = """
                /**
                 * %s 服务层接口实现类
                 */
                @Log4j2
                @Service
                @RequiredArgsConstructor
                public class %sServiceImpl implements %sService { 
                    private final %sRepository %sRepository;
                """.formatted(tableInfo.getRemark(),upName,upName,upName,tableInfo.getLowerName());

        channel.writeNewline(project.getBasePackageImport() + project.getServicePackage() + ".impl;");
        channel.writeEmptyLine();
        channel.writeNewline(ImportConstant.LOMBOK_REQ_CONS);
        channel.writeNewline(ImportConstant.LOG4J2);
        channel.writeNewline(ImportConstant.SPRING_SERVICE);
        channel.writeNewline(ImportConstant.COMMON_PAGE);
        channel.writeNewline(project.getBaseImport() + project.getServicePackage() + "." + upName + "Service;");
        channel.writeNewline(project.getBaseImport() + project.getRepositoryPackage() + "." + upName + "Repository;");
        channel.writeNewline(project.getEntityImport());
        channel.writeNewline(ImportConstant.LIST);
        channel.writeNewline(classDefine);
        writeMethod(upName,tableInfo.getLowerName(),tableInfo.getRemark());
        channel.writeNewline("}");
    }

    private void writeMethod(String upName,String loName,String remark){
        String save = """
                    @Override
                    public int save(%s pojo) {
                        log.debug("添加%s数据: {}",pojo);
                        return this.%sRepository.append(pojo);
                    }
                """.formatted(upName,remark,loName);

        String saveAndReturn = """
                    @Override
                    public %s saveAndReturn(%s pojo) {
                        if (this.save(pojo) == 1){
                            log.debug("添加并反回数据,执行添加成功");
                            return this.findById(pojo.getId());
                        }else {
                            log.info("添加并反回数据,添加失败");
                            return null;
                        }
                    }
                """.formatted(upName,upName);
        String removeById = """
                    @Override
                    public int removeById(Integer id) {
                        log.debug("根据数据编号删除%s数据: {}",id);
                        return this.%sRepository.cancel(id);
                    }
                """.formatted(remark,loName);
        String edit = """
                    @Override
                    public int edit(%s pojo) {
                        log.debug("更新%s数据,根据编号进行更新: {}",pojo);
                        return this.%sRepository.modify(pojo);
                    }
                """.formatted(upName,remark,loName);
        String editAndReturn = """
                    @Override
                    public %s editAndReturn(%s pojo) {
                        if (this.edit(pojo) == 1){
                            log.debug("更新并反回数据执行更新成功");
                            return this.findById(pojo.getId());
                        }else {
                            log.info("更新并反回数据执行更新失败");
                            return null;
                        }
                    }
                """.formatted(upName,upName);
        String findById = """
                    @Override
                    public %s findById(Integer id) {
                        log.debug("使用%s数据编号查找数据: {}",id);
                        return this.%sRepository.searchById(id);
                    }
                """.formatted(upName,remark,loName);
        String findList = """
                    @Override
                    public List<%s> findList() {
                        log.debug("查找全部%s数据列表");
                        return this.%sRepository.searchList();
                    }
                """.formatted(upName,remark,loName);
        String findLimit = """
                    @Override
                    public List<%s> findLimit(int start, int end) {
                        log.debug("查找指定区间的%s数据列表: {}-{}",start,end);
                        return this.%sRepository.searchLimit(start,end);
                    }
                """.formatted(upName,remark,loName);
        String findCount = """
                    @Override
                    public Long findCount() {
                        log.debug("查找全部数据量");
                        return %sRepository.searchCount("");
                    }
                """.formatted(loName);
        String findPage = """
                    @Override
                    public Page<%s> findPage(int currentPage, int pageSize) {
                        log.debug("查找%s分页数据: 当前页={},页大小={}",currentPage,pageSize);
                        return Page.<%s>builder()
                                .total(this.findCount())
                                .current(currentPage)
                                .pageSize(pageSize)
                                .build(this::findLimit);
                    }
                """.formatted(upName,remark,upName);
        channel.writeNewline(save);
        channel.writeNewline(saveAndReturn);
        channel.writeNewline(removeById);
        channel.writeNewline(edit);
        channel.writeNewline(editAndReturn);
        channel.writeNewline(findById);
        channel.writeNewline(findList);
        channel.writeNewline(findLimit);
        channel.writeNewline(findCount);
        channel.writeNewline(findPage);
    }

    @Override
    public boolean isWriterFile(CreateProps create) {
        return create.isCreateServiceImpl();
    }

    @Override
    public Path getFilePath(String basePath, ProjectProps project, String fileName) {
        return Paths.get(basePath, project.getServicePackage(),"impl",fileName + "ServiceImpl.java");
    }
}
